package com.example.demo.threadCommunication;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @desc: <br/>
 * @author: Jingbo Hu<br/>
 * @time：2020年06⽉29⽇<br/>
 * @version：v1.0.0<br>
 */
@Slf4j
public class WaitNotifyDemo {

    private static final Object lock = new Object();
    private static boolean flag = false;

    /**
     * 等待/通知的经典范式
     *
     * @param args
     */
    public static void main(String[] args) {

        /**
         * 等待方遵循如下原则。
         * 1）获取对象的锁。
         * 2）如果条件不满足，那么调用对象的wait()方法，被通知后仍要检查条件。
         * 3）条件满足则执行对应的逻辑
         */
        new Thread(() -> {
            synchronized (lock) {
                while (!flag) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.info("执行剩余任务...");
            }
        }).start();

        /**
         * 通知方遵循如下原则。
         * 1）获得对象的锁。
         * 2）改变条件。
         * 3）通知所有等待在对象上的线程
         */
        new Thread(() -> {
            synchronized (lock) {
                flag = true;
                for (int i = 1; i <= 10; i++) {
                    log.info("正在执行任务...{}%", i * 10);
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.notifyAll();
            }
        }).start();

    }
}
